#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <list>
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_CommHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_Types.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_ProtocolHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine/NetEngine_Core/NetCore_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine/NetEngine_Core/NetCore_Error.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_Client/NetClient_Socket/NetClient_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_Client/NetClient_Socket/NetClient_Error.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_RfcComponents/RfcComponents_WSFrame/WSFrame_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_RfcComponents/RfcComponents_WSFrame/WSFrame_Error.h"

//g++ -std=gnu++11 -Wall -g Test_WSSocket.cpp -o Test_WSSocket -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_Core -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_Client -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_RfcComponents -lNetEngine_BaseLib -lNetEngine_Algorithm -lNetEngine_ManagePool -lNetEngine_Core -lNetClient_Socket -lRfcComponents_WSFrame -lpthread -Wl,-rpath=../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_Core:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_Client:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_RfcComponents,--disable-new-dtags


BOOL bConnect = FALSE;
XNETHANDLE xhToken;
TCHAR tszClientAddr[64];

BOOL __stdcall NetCore_CB_Login(LPCSTR lpszClientAddr, SOCKET hSocket, LPVOID lParam)
{
    _tcscpy(tszClientAddr, lpszClientAddr);
    printf("NetCore_CB_Login:%s\n", lpszClientAddr);
    RfcComponents_WSPacket_Create(lpszClientAddr);
    return TRUE;
}
void __stdcall NetCore_CB_Recv(LPCSTR lpszClientAddr, SOCKET hSocket, LPCSTR lpszRecvMsg, int nMsgLen, LPVOID lParam)
{
    printf("NetCore_CB_Recv:%s-%d\n", lpszClientAddr, nMsgLen);
    if (bConnect)
    {
        /*
        int nSDLen = 0;
        TCHAR tszRecvBuffer[2048];
        TCHAR tszSendBuffer[2048];

        memset(tszRecvBuffer, '\0', sizeof(tszRecvBuffer));
        memset(tszSendBuffer, '\0', sizeof(tszSendBuffer));

        RfcComponents_WSCodec_DecodeMsg(lpszRecvMsg, &nMsgLen, tszRecvBuffer);
        printf("%s\n", tszRecvBuffer);
        nSDLen = _tcslen(tszRecvBuffer);
        RfcComponents_WSCodec_EncodeMsg(tszRecvBuffer, tszSendBuffer, &nSDLen, ENUM_XENGINE_RFCOMPONENTS_WEBSOCKET_OPCODE_TEXT);
        NetCore_TCPEPoll_SendEx(xhToken, lpszClientAddr, tszSendBuffer, nSDLen);
        */
        if (!RfcComponents_WSPacket_Post(lpszClientAddr, lpszRecvMsg, nMsgLen))
        {
            printf("RfcComponents_WSPacket_Post:%lX\n", WSFrame_GetLastError());
        }
    }
    else
    {
        int nSDLen = nMsgLen;
        TCHAR tszHandsBuffer[1024];
        memset(tszHandsBuffer, '\0', sizeof(tszHandsBuffer));

        RfcComponents_WSConnector_HandShake(lpszRecvMsg, &nSDLen, tszHandsBuffer);
        NetCore_TCPEPoll_SendEx(xhToken, lpszClientAddr, tszHandsBuffer, nSDLen);
        bConnect = TRUE;
    }
}
void __stdcall NetCore_CB_Close(LPCSTR lpszClientAddr, SOCKET hSocket, LPVOID lParam)
{
    printf("NetCore_CB_Close:%s\n", lpszClientAddr);
    RfcComponents_WSPacket_Delete(lpszClientAddr);
}

LPVOID NetCore_Thread(LPVOID lParam)
{
    while (TRUE)
    {
        if (RfcComponents_WSPacket_WaitEvent())
        {
            int nMsgLen = 20480;
            ENUM_XENGINE_RFCOMPONENTS_WEBSOCKET_OPCODE enOPCode;
            TCHAR tszMsgBuffer[20480];
            TCHAR tszClientAddr[64];

            memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
            memset(tszClientAddr, '\0', sizeof(tszClientAddr));

            if (RfcComponents_WSPacket_GetRandom(tszClientAddr, tszMsgBuffer, &nMsgLen, &enOPCode))
            {
                printf("%s %d:%s\n", tszClientAddr, nMsgLen, tszMsgBuffer);
            }
        }
        Sleep(1);
    }
    return NULL;
}

int main1()
{
    memset(tszClientAddr, '\0', sizeof(tszClientAddr));

    if (!NetCore_TCPEPoll_StartEx(&xhToken, 5000, 100, 2))
    {
        printf("%lX\n", NetCore_GetLastError());
        return 0;
    }
    NetCore_TCPEPoll_RegisterCallBackEx(xhToken, NetCore_CB_Login, NetCore_CB_Recv, NetCore_CB_Close);
    pthread_t hThread;
    pthread_create(&hThread,NULL, NetCore_Thread, NULL);
    while (1)
    {
        Sleep(1000);
    }
    return 0;
}
int main()
{
    int nLen = 0;
    TCHAR tszKeyBuffer[1024];
    TCHAR tszMsgBuffer[1024];

    memset(tszKeyBuffer, '\0', sizeof(tszKeyBuffer));
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));

    if (!RfcComponents_WSConnector_Connect(tszKeyBuffer, tszMsgBuffer, &nLen))
    {
        printf("RfcComponents_WSConnector_Connect:%lX", WSFrame_GetLastError());
        return -1;
    }

    SOCKET hSocket = 0;
    if (!NetClient_TCPSelect_Create(_T("121.40.165.18"), 8800, &hSocket))
    {
        printf("NetClient_TCPSelect_Create:%lX", NetClient_GetLastError());
        return -1;
    }

    if (!NetClient_TCPSelect_SendMsg(hSocket, tszMsgBuffer, nLen))
    {
        printf("NetClient_TCPSelect_SendMsg:%lX", NetClient_GetLastError());
        return -1;
    }

    int nPos = 0;
    nLen = 1024;
    memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
    if (!NetClient_TCPSelect_RecvMsg(hSocket, tszMsgBuffer, &nLen, FALSE))
    {
        printf("NetClient_TCPSelect_RecvMsg:%lX", NetClient_GetLastError());
        return -1;
    }
    if (!RfcComponents_WSConnector_VerConnect(tszKeyBuffer, tszMsgBuffer, &nPos))
    {
        printf("RfcComponents_WSConnector_VerConnect:%lX", WSFrame_GetLastError());
        return -1;
    }

    if (nPos > 0)
    {
        printf("%s\n", tszMsgBuffer + nPos);
    }
    while (1)
    {
        int nRVLen = 6;
        TCHAR tszRecvBuffer[2048];
        TCHAR tszMsgBuffer[2048];

        memset(tszRecvBuffer, '\0', sizeof(tszRecvBuffer));
        memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));

        if (RfcComponents_WSCodec_EncodeMsg("123456", tszMsgBuffer, &nRVLen, ENUM_XENGINE_RFCOMPONENTS_WEBSOCKET_OPCODE_TEXT, TRUE))
        {
            if (NetClient_TCPSelect_SendMsg(hSocket, tszMsgBuffer, nRVLen))
            {
                printf("NetClient_TCPSelect_SendMsg:%d\n", nRVLen);
            }
        }

        nRVLen = 2048;
        memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
        if (NetClient_TCPSelect_RecvMsg(hSocket, tszRecvBuffer, &nRVLen, FALSE))
        {
            RfcComponents_WSCodec_DecodeMsg(tszRecvBuffer, &nRVLen, tszMsgBuffer);
            printf("%s\n", tszMsgBuffer);
        }
    }
    return 0;
}
